import { defineComponent, PropType, VNodeChild, App, computed, getCurrentInstance } from 'vue'
import useMemo from '../_util/hooks/useMemo'
import { getComponent } from '../_util/props-util'

const prefixCls = 'x-switch'

const Switch = defineComponent({
  name: 'x-switch',
  props: {
    value: [Boolean, Number, String],
    disabled: Boolean,
    checked: [String, Object] as PropType<VNodeChild>,
    unchecked: [String, Object] as PropType<VNodeChild>,
    checkedValue: { type: [Boolean, Number, String], default: true },
    uncheckedValue: { type: [Boolean, Number, String], default: false },
  },
  emits: ['update:value', 'change'],
  setup(props, { emit }) {
    const { proxy: vm } = getCurrentInstance()
    const valueRef = useMemo(() => props.value)
    const checkedRef = computed(() => valueRef.value === props.checkedValue)
    
    function setChecked(checked: boolean) {
      if (props.disabled) return
      valueRef.value = checked ? props.checkedValue : props.uncheckedValue
      emit('update:value', valueRef.value)
      emit('change', valueRef.value)
    }

    function onClick() {
      setChecked(!checkedRef.value)
    }

    return () => {
      const cls = [prefixCls, {
          [`${prefixCls}-checked`]: checkedRef.value,
          [`${prefixCls}-disabled`]: props.disabled
      }]
      const switchProps = {
        class: cls,
        disabled: props.disabled,
        role: 'switch',
        'aria-checked': checkedRef.value
      }

      const node = getComponent(vm, checkedRef.value ? 'checked' : 'unchecked')
      const prefixNode = node ? <div class={`${prefixCls}-text`}>{node}</div> : undefined

      return (
        <button {...switchProps} type='button' onClick={onClick}>
          <div class={`${prefixCls}_core`}></div>
          {prefixNode}
        </button>
      )
    }
  }
})

Switch.install = (app: App) => {
  app.component(Switch.name, Switch)
}

export default Switch